package ads.pin.pinmon.business;

import java.sql.SQLException;
import java.util.List;

import ads.pin.pinmon.dal.CreatureDAO;
import ads.pin.pinmon.dal.CreatureSkillDAO;
import ads.pin.pinmon.entity.Creature;
import ads.pin.pinmon.entity.Skill;
import ads.pin.pinmon.exception.BusinessException;

public class CreatureBO {

	/**
	 * Salva a criatura no banco de dados. Tambem salva as skills da criatura na
	 * tabela de juncao.
	 * 
	 * @param creature
	 *            Criatura a ser salva.
	 * 
	 * @throws BusinessException
	 */
	public void saveCreature(Creature creature) throws BusinessException {

		if (checkCompatibleKind(creature)) {
			try {
				CreatureDAO creatureDAO = new CreatureDAO();
				CreatureSkillDAO creatureSkillDAO = new CreatureSkillDAO();

				creatureDAO.save(creature);
				creature.setId(creatureDAO.searchByMaxId().getId());

				creatureSkillDAO.saveCreatureSkill(creature);

			} catch (SQLException e) {
				e.printStackTrace();
				// TODO add error msg -> failed to insert into database!
				throw new BusinessException(null);

			} catch (Exception e) {
				e.printStackTrace();

			}

		} else
			// TODO add error msg -> creature and skill kind are different!
			throw new BusinessException(null);
	}

	/**
	 * Atualiza a criatura no banco de dados.
	 * 
	 * @param creature
	 *            Criatura a ser atualizada.
	 * @throws BusinessException
	 */
	public void updateCreature(Creature creature) throws BusinessException {
		if (checkCompatibleKind(creature)) {
			try {
				CreatureDAO creatureDAO = new CreatureDAO();
				creatureDAO.update(creature);

			} catch (SQLException e) {
				e.printStackTrace();
				// TODO add error msg -> failed to insert into database!
				throw new BusinessException(null);
			}

		} else
			// TODO add error msg -> creature and skill kind are different!
			throw new BusinessException(null);

	}

	/**
	 * Deleta uma criatura pelo id no banco de dados.
	 * 
	 * @param id
	 *            Valor do Id da criatura.
	 * @throws BusinessException
	 */
	public void deleteCreatureById(int id) throws BusinessException {
		CreatureDAO creatureDAO = new CreatureDAO();

		try {
			creatureDAO.deleteById(id);
		} catch (SQLException e) {
			e.printStackTrace();
			// TODO add error msg -> failed to insert into database!
			throw new BusinessException(null);
		}
	}

	/**
	 * Deleta todas as criaturas no banco de dados.
	 * 
	 * @throws BusinessException
	 */
	public void deleteAllCreatures() throws BusinessException {
		CreatureDAO creatureDAO = new CreatureDAO();
		try {
			creatureDAO.deleteAll();
		} catch (SQLException e) {
			e.printStackTrace();
			// TODO add error msg -> failed to insert into database!
			throw new BusinessException(null);
		}
	}

	/**
	 * Procura uma criatura pelo Id.
	 * 
	 * @param id
	 *            Identificador da criatura.
	 * @return Criatura escolhida.
	 * @throws BusinessException
	 */
	public Creature searchCreatureById(int id) throws BusinessException {
		CreatureDAO creatureDAO = new CreatureDAO();
		try {
			return creatureDAO.searchById(id);
		} catch (SQLException e) {
			e.printStackTrace();
			// TODO add error msg -> failed to insert into database!
			throw new BusinessException(null);
		}

	}

	/**
	 * Procura a criatura de maior Id.
	 * 
	 * @return Criatura de maior Id.
	 * @throws BusinessException
	 */
	public Creature searchCreatureByMaxId() throws BusinessException {
		CreatureDAO creatureDAO = new CreatureDAO();
		try {
			return creatureDAO.searchByMaxId();
		} catch (SQLException e) {
			e.printStackTrace();
			// TODO add error msg -> failed to insert into database!
			throw new BusinessException(null);
		}
	}

	/**
	 * Procura as criaturas do tipo especificado.
	 * 
	 * @param obj
	 *            Tipo escolhido.
	 * @return Lista com criaturas do tipo escolhido.
	 * @throws BusinessException
	 */
	public List<Creature> searchCreatureByKind(Object obj)
			throws BusinessException {
		CreatureDAO creatureDAO = new CreatureDAO();
		try {
			return creatureDAO.searchByKind(obj);
		} catch (SQLException e) {
			e.printStackTrace();
			// TODO add error msg -> failed to insert into database!
			throw new BusinessException(null);
		}
	}

	/**
	 * 
	 * @param author
	 * @return
	 * @throws BusinessException
	 */
	public List<Creature> searchCreatureByAuthor(String author)
			throws BusinessException {
		CreatureDAO creatureDAO = new CreatureDAO();
		try {
			return creatureDAO.searchByAuthor(author);
		} catch (SQLException e) {
			e.printStackTrace();
			// TODO add error msg -> failed to insert into database!
			throw new BusinessException(null);
		}
	}

	/**
	 * 
	 * @param name
	 * @return
	 * @throws BusinessException
	 */
	public List<Creature> searchCreatureByName(String name)
			throws BusinessException {
		CreatureDAO creatureDAO = new CreatureDAO();
		try {
			return creatureDAO.searchByName(name);
		} catch (SQLException e) {
			e.printStackTrace();
			// TODO add error msg -> failed to insert into database!
			throw new BusinessException(null);
		}
	}

	/**
	 * Checa se as skills passadas e a criatura sao do mesmo tipo. Se estiver
	 * tudo certo, salva a criatura e as skills pertencentes a ela.
	 * 
	 * @param creature
	 *            Criatura a ser checada.
	 * @param skills
	 *            Lista de skills a serem checadas.
	 * @throws BusinessException
	 */
	private boolean checkCompatibleKind(Creature creature)
			throws BusinessException {

		for (Skill s : creature.getSkills()) {
			if (!s.getKind().equalsIgnoreCase(creature.getKind()))
				return false;

		}

		return true;
	}
}
